"""
deepdiff 是一个Python库，用于比较Python数据结构（例如字典、列表、JSON等）之间的差异。它不仅可以比较简单的Python数据类型，还可以比较任意深度或
复杂度的数据结构。
在Python中，我们经常需要比较两个JSON对象的异同。例如测试中，我们需要比较预期输出和实际输出是否相同。而在开发中，我们也需要比较两个JSON对象的差异
以便维护。使用 deepdiff 库，可以轻松处理这些场景。


DeepDiff库的主要模块如下：
1. deepdiff.DeepDiff ：这是DeepDiff库的核心模块，提供了比较两个对象之间差
异的功能。它可以比较字典、列表、集合等复杂对象，并返回差异的详细信息。
2. deepdiff.DeepSearch ：这是一个工具类，用于在复杂对象中搜索指定值。它可
以深度遍历对象，并返回找到的匹配项的路径信息。
3. deepdiff.DeepHash ：这个模块用于生成复杂对象的哈希值。它可以递归地计算
对象的哈希值，并考虑对象中的差异。

这些模块是DeepDiff库的核心组成部分，提供了强大的功能来比较和分析复杂对象之
间的差异。使用DeepDiff库，你可以轻松地比较不同数据结构之间的差异，以便进行
对象状态跟踪、测试验证和数据版本控制等应用。

在安装deepdiff之前，请确保你的Python版本为3.6及以上。 然后，可以通过以下命
令安装deepdiff：

1 pip install deepdiff


如果实际请求结果和预期值的json数据都一致，那么会返回 {} 空字典，否则会返回
对比差异的结果，接口测试中我们也可以根据这个特点进行断言。
如果对比结果不同，将会给出下面对应的返回：
1. type_changes：类型改变的key
2. values_changed：值发生变化的key
3. dictionary_item_added：字典key添加
4. dictionary_item_removed：字段key删除
"""

from deepdiff import DeepDiff,DeepHash,DeepSearch,extract
import json


# json1 = {
#     "code": 0,
#     "message": "成功",
#     "data": {
#         "total": 28,
#         "id": 123
#     }
# }

# 一样的数据，返回{}
# json2 = {
#     "code": 0,
#     "message": "成功",
#     "data": {
#         "total": 28,
#         "id": 123
#     }
# }

#print(DeepDiff(json1, json2))

# json1 = {"code":0,"message":"成功","data":{"total":28,"id":123}}
#
# json2 = {"code":0,"message":"成功","data":{"total":28,"id":"123"}}
#案例二：修改对应的类型：{'type_changes':{值:具体的值},
"""
{'type_changes': {"root['data']['id']": {'old_type': <class 'int'>, 'new_type': <class 'str'>, 'old_value': 123, 'new_value': '123'}}}

"""

# 案例三：修改对应的数据：{'values_changed':{值:具体的值}}
#{'values_changed': {"root['data']['id']": {'new_value': 476, 'old_value': 123}}}
# json1 = {"code":0,"message":"成功","data":{"total":28,"id":123}}
#
# json2 = {"code":0,"message":"成功","data":{"total":28,"id":476}}


# 案例四：添加值：{'dictionary_item_added':{值:具体的值}
#{'dictionary_item_added': ["root['uuid']", "root['data']['goodsname']"]}
# json1 = {"code":0,"message":"成功","data":{"total":28,"id":123}}
#
# json2 = {"code":0,"message":"成功","data":{"total":28,"id":123,"goodsname":"鸡肉"},"uuid":"1111"}



# 案例五：删除值：删除值：{'dictionary_item_removed':{值:具体的值}
#{'dictionary_item_removed': ["root['uuid']", "root['data']['goodsname']"]}
# json1 = {"code":0,"message":"成功","data":{"total":28,"id":123,"goodsname":"鸡肉"},"uuid":"1111"}
#
#
# json2 = {"code":0,"message":"成功","data":{"total":28,"id":123}}

# print(DeepDiff(json.dumps(json1), json.dumps(json2)))


# 字典是无序的， 顺序不一致，内容一样，对比是一样的
# json1 = {"code":0,"message":"成功","data":{"total":28,"id":123}}
#
# json2 = {"data":{"total":28,"id":123},"code":0,"message":"成功"}


# 列表：1,一样
# json1 = [1,2,2,3,4,"felix"]
# json2 = [1,2,2,3,4,"felix"]

# 列表：2,顺序不一样，
# {'values_changed': {'root[0]': {'new_value': 3, 'old_value': 1}, 'root[3]': {'new_value': 1, 'old_value': 3}}}
# json1 = [1,2,2,3,4,"felix"]
# json2 = [3,2,2,1,4,"felix"]

# 列表：3,值的类型不一样
#{'type_changes': {'root[3]': {'old_type': <class 'int'>, 'new_type': <class 'str'>, 'old_value': 3, 'new_value': '3'}}}
# json1 = [1,2,2,3,4,"felix"]
# json2 = [1,2,2,"3",4,"felix"]


# 列表：4,新增一个值
#{'type_changes': {'root[3]': {'old_type': <class 'int'>, 'new_type': <class 'str'>, 'old_value': 3, 'new_value': '3'}}, 'iterable_item_added': {'root[6]': 5}}
# json1 = [1,2,2,3,4,"felix"]
# json2 = [1,2,2,"3",4,"felix",5]


# 列表：4,删除
#{'iterable_item_removed': {'root[3]': 3}}
# json1 = [1,2,2,3,4,"felix"]
# json2 = [1,2,2,4,"felix"]



"""

其实，在实际接口断言中，可能需要校验的字段顺序不一样，又或者有一些字段值
不需要，为了解决这类问题，Deepdiff也提供了相信的参数，只需要在比较的时候加
入，传入对应参数即可。
ignore_order(忽略排序)
ignore_string_case(忽略大小写)
exclude_paths排除指定的字段

"""

# json1 = [1,2,3,{"code":0,"message":"成功","data":{"total":28,"id":123},"name": "felix","desc":"red"}]
#
# json2 = [1,3,2,{"code":0,"message":"成功","data":{"total":28,"id":"123"},"Name": "felix","desc":"Red"}]


# df1 = DeepDiff(json1,json2,ignore_string_case=False,ignore_order=True, exclude_paths={"root[3]['data']['id']"}, view="tree")
"""
print(df1.pretty())  --- 可视化阅读
Item root[3]['Name'] added to dictionary.
Item root[3]['name'] removed from dictionary.
Value of root[3]['desc'] changed from "red" to "Red".
"""

"""
ignore_string_type_changes
忽略字符串类型的更改。例如，如果ignore_string_type_changes设置为True，则b "
Hello "与" Hello "被认为是相同的。默认为：False

"""








"""
ignore_string_type_changes
忽略字符串类型的更改。例如，如果ignore_string_type_changes设置为True，则b "
Hello "与" Hello "被认为是相同的。默认为：False

"""

# json1 = [1,2,3,11,b"Hello",{"code":0,"message":"成功","data":{"total":28,"id":123},"name": "felix","desc":"red"}]
#
# json2 = [1,3,2,11.0,"Hello",{"code":0,"message":"成功","data":{"total":28,"id":"123"},"Name": "felix","desc":"Red"}]
#
# df1 = DeepDiff(json1,json2,ignore_string_type_changes=True,ignore_numeric_type_changes=True)

"""
ignore_string_type_changes=False,ignore_numeric_type_changes=False

Item root[5]['Name'] added to dictionary.
Item root[5]['name'] removed from dictionary.
Type of root[3] changed from int to float and value changed from 11 to 11.0.
Type of root[4] changed from bytes to str and value changed from b'Hello' to "Hello".
Type of root[5]['data']['id'] changed from int to str and value changed from 123 to "123".
Value of root[1] changed from 2 to 3.
Value of root[2] changed from 3 to 2.
Value of root[5]['desc'] changed from "red" to "Red".


ignore_string_type_changes=True,ignore_numeric_type_changes=True
Item root[5]['Name'] added to dictionary.
Item root[5]['name'] removed from dictionary.
Type of root[5]['data']['id'] changed from int to str and value changed from 123 to "123".
Value of root[1] changed from 2 to 3.
Value of root[2] changed from 3 to 2.
Value of root[5]['desc'] changed from "red" to "Red".
"""

# print(df1.pretty())



# json1 = [1,2,3,11,"Hello",{"code":0,"message":"成功","data":{"total":28,"id":123},"name": "felix","desc":"red"}]


# ds = DeepSearch(json1,"red",use_regexp=True)

"""
{'matched_values': ["root[5]['desc']"]}
"""
# print(ds)
#
# dhash = DeepHash(json1)

"""
{1: 'c1800a30c736483f13615542e7096f7973631fef8ca935ee1ed9f35fb06fd44e', 
2: '610e2bb86cee5362640bd1ab01b8a4a4559cced9dd6058376894c041629a7b69', 
3: '867a472b6fb448c5e78e8a6bfabf07e6c76733e0c44ddf99cbb55c17d7f86504', 
11: 'fa26322d0f2ff88344439244a7df169ea50f03fa52ec69ff090791329db4e06f', 
'Hello': 'ffb1b180a91bbd7f3f3ab46fa61ebebf1e6e49537f014a450fbcbd9b44aa5c7a', 
'code': '1fd768a075ff2481f101c38e2e135927f4dbac3426f8968c1d514314c2fbd1d5', 
0: '0721514aeeb11d91796d9f3769a20fde80566ddf03ce7f00832632...}

"""
# print(dhash)



json1 = [1,2,3,11,"Hello",{"code":0,"message":"成功","data":{"total":28,"id":123},"name": "felix","desc":"red"}]


path = "root[5]['desc']"

"""
该模块可以根据值抽取其Key的路径；反过来根据Key路径提取其值。
"""

print(extract(json1,path))   # red